use indexmap::IndexMap;
use serde_json::from_str;
use std::env;
use std::io::{BufRead, BufReader};
use std::process::{Command, Stdio};
use std::thread;

use subprocess::Exec;

#[derive(Debug, serde::Deserialize)]
struct AppConfig {
    app: Vec<String>,
    flag: u8,
}

// 嵌入配置文件
const ICON_CONFIG_STR: &str = include_str!("../../config/icon.json");
const NVIDIA_CONFIG_STR: &str = include_str!("../../config/nvidia.json");
const APP_CONFIG_STR: &str = include_str!("../../config/app.json");
const SYS_CONFIG_STR: &str = include_str!("../../config/sys.json");

// 解析配置文件
fn parse_config(config_str: &str) -> IndexMap<String, IndexMap<String, AppConfig>> {
    from_str(config_str).expect("Failed to parse JSON")
}

// 执行命令
fn exec_command(config: &IndexMap<String, AppConfig>) {
    for (key, app_config) in config.iter() {
        if app_config.flag == 0 {
            continue;
        }
        for cmd in &app_config.app {
            println!("{}", key);
            let output = Exec::shell(cmd)
                .capture()
                .expect("Failed to execute command");
            println!("Return code: {:#?}", output.exit_status);
            println!("Stdout: {}", String::from_utf8_lossy(&output.stdout));
            println!("Stderr: {}", String::from_utf8_lossy(&output.stderr));
        }
    }
}

fn main() {
    // 解析配置文件
    let icon_config = parse_config(ICON_CONFIG_STR);
    let nvidia_config = parse_config(NVIDIA_CONFIG_STR);
    let app_config = parse_config(APP_CONFIG_STR);
    let sys_config = parse_config(SYS_CONFIG_STR);
    println!(
        "{:#?},{:#?},{:#?},{:#?}",
        icon_config, nvidia_config, app_config, sys_config
    );

    let args = env::args().collect::<Vec<String>>();
    let linux_name = &args[1];

    // 执行应用相关命令
    exec_command(&app_config.get(linux_name).unwrap());

    // 执行系统相关命令
    exec_command(&sys_config.get(linux_name).unwrap());
    // 执行美化相关命令
    exec_command(&icon_config.get(linux_name).unwrap());
    // 执行 NVIDIA 相关命令
    exec_command(&nvidia_config.get(linux_name).unwrap());
}
